package com.qttaudio.example;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.qttaudio.example.utils.DensityUtils;
import com.qttaudio.example.utils.Utils;
import com.qttaudio.ios.demo.R;
import com.qttaudio.sdk.channel.AudioOutput;
import com.qttaudio.sdk.channel.ChannelEngine;
import com.qttaudio.sdk.channel.ChannelFactory;
import com.qttaudio.sdk.channel.ChannelObserver;
import com.qttaudio.sdk.channel.ChannelRole;
import com.qttaudio.sdk.channel.ChannelUser;
import com.qttaudio.sdk.video.FrameFormat;
import com.qttaudio.sdk.video.QttCameraView;
import com.qttaudio.sdk.video.VideoDisplayer;
import com.qttaudio.sdk.video.VideoGLView;
import com.qttaudio.sdk.video.VideoPlugin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by Administrator on 2019/9/6 0006.
 */

public class RoomVideoActivity extends BaseAvtivity implements VideoDisplayer {

    @BindView(R.id.tv_time)
    TextView tvTime;
    @BindView(R.id.btMute)
    ToggleButton btMute;
    @BindView(R.id.btClose)
    Button btClose;
    @BindView(R.id.btLoudspeaker)
    ToggleButton btLoudspeaker;
    @BindView(R.id.tv_mute)
    TextView tvMute;
    @BindView(R.id.tv_loudspeaker)
    TextView tvLoudspeaker;
    @BindView(R.id.remoteView)
    VideoGLView remoteView;
    @BindView(R.id.localView)
    QttCameraView localView;
    @BindView(R.id.rootlayout)
    RelativeLayout rootlayout;
    @BindView(R.id.remoteView_top_left)
    VideoGLView remoteViewTopLeft;
    @BindView(R.id.ll_video_top_left)
    LinearLayout llVideoTopLeft;
    @BindView(R.id.ll_video_top_right)
    LinearLayout llVideoTopRight;
    @BindView(R.id.ll_video_top)
    LinearLayout llVideoTop;
    @BindView(R.id.remoteView_bottom_left)
    VideoGLView remoteViewBottomLeft;
    @BindView(R.id.ll_video_bottom_left)
    LinearLayout llVideoBottomLeft;
    @BindView(R.id.remoteView_bottom_right)
    VideoGLView remoteViewBottomRight;
    @BindView(R.id.ll_video_bottom_right)
    LinearLayout llVideoBottomRight;
    @BindView(R.id.ll_video_bottom)
    LinearLayout llVideoBottom;


    private long roomId = 0;
    public static long mUid = -1;
    private ChannelEngine channelEngine = null;
    private ChannelObserverImpl channelObserver = null;
    private Context context = null;

    private List<Long> videoViewList = new ArrayList<>();
    private Map<Long, VideoGLView> videoMapViewList = new HashMap<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_roomvideo);
        ButterKnife.bind(this);
        btMute.setVisibility(View.INVISIBLE);
        localView.setZOrderOnTop(true);
        VideoPlugin.SetVideoCard(localView, this, FrameFormat.YUV420P);
        context = this;
        roomId = Long.parseLong(getIntent().getStringExtra("roomId"));
        if (mUid < 0) {
            mUid = new Random().nextInt(100000);
        }
        channelObserver = new ChannelObserverImpl();

        channelEngine = ChannelFactory.GetChannelInstance();
        channelEngine.setUid(mUid);
        channelEngine.setObserver(channelObserver);
        ChannelRole mRole = ChannelRole.TALKER;
        channelEngine.join(roomId, mRole);

        btClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                channelEngine.leave();
            }
        });
        btLoudspeaker.setChecked(true);
        AudioOutput.routeAudioTo(AudioOutput.SPEAKER);
        btLoudspeaker.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (b)
                    AudioOutput.routeAudioTo(AudioOutput.SPEAKER);
                else
                    AudioOutput.routeAudioTo(AudioOutput.HEADPHONE);

            }
        });
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            showExitRoomDialog();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

//    @Override
//    protected void onResume() {
//        super.onResume();
////        localView.OpenCamera();
//        localView.startPreview(true);
//    }
//
//    @Override
//    protected void onPause() {
//        super.onPause();
////        localView.OpenCamera();
//        localView.startPreview(false);
//    }


    private void addVideoView(Long userid) {
        synchronized (videoViewList) {
            if (videoViewList.size() >= 3) {
                return;
            }
            if (!videoViewList.contains(userid)) {
                videoViewList.add(userid);
                setViewVisibility();
            }
        }

    }

    private void removeVideoView(Long userid) {
        synchronized (videoViewList) {
            if (videoViewList.size() <= 1) {
                return;
            }
            if (videoViewList.contains(userid)) {
                videoViewList.remove(userid);
                setViewVisibility();
            }
        }

    }


    private void setViewVisibility() {
        Log.i("","k_test setViewVisibility  videoViewList.size():"+videoViewList.size());
        int count = videoViewList.size();
        if (count == 1) {
            remoteView.setVisibility(View.VISIBLE);
            llVideoBottom.setVisibility(View.INVISIBLE);
            llVideoTopLeft.setVisibility(View.INVISIBLE);
            remoteViewBottomLeft.setVisibility(View.GONE);
            remoteViewBottomRight.setVisibility(View.GONE);
            remoteViewTopLeft.setVisibility(View.GONE);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) localView.getLayoutParams();
            int px20 = DensityUtils.dip2px(context, 20);
            layoutParams.setMargins(px20, px20, px20, px20);
            localView.setLayoutParams(layoutParams);

            remoteView.attachDisplayId(videoViewList.get(0));
            videoMapViewList.put(videoViewList.get(0), remoteView);

        } else if (count == 2) {
            remoteView.setVisibility(View.GONE);
            llVideoBottom.setVisibility(View.VISIBLE);
            llVideoTopLeft.setVisibility(View.GONE);
            remoteViewBottomLeft.setVisibility(View.VISIBLE);
            remoteViewBottomRight.setVisibility(View.VISIBLE);
            remoteViewTopLeft.setVisibility(View.GONE);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) localView.getLayoutParams();
            layoutParams.setMargins(0, 0, 0, 0);
            localView.setLayoutParams(layoutParams);

            remoteViewBottomLeft.attachDisplayId(videoViewList.get(0));
            videoMapViewList.put(videoViewList.get(0), remoteViewBottomLeft);
            remoteViewBottomRight.attachDisplayId(videoViewList.get(1));
            videoMapViewList.put(videoViewList.get(1), remoteViewBottomRight);


        } else if (count == 3) {
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) localView.getLayoutParams();
            layoutParams.setMargins(0, 0, 0, 0);
            localView.setLayoutParams(layoutParams);

            remoteView.setVisibility(View.GONE);
            llVideoBottom.setVisibility(View.VISIBLE);
            llVideoTopLeft.setVisibility(View.VISIBLE);
            remoteViewBottomLeft.setVisibility(View.VISIBLE);
            remoteViewBottomRight.setVisibility(View.VISIBLE);
            remoteViewTopLeft.setVisibility(View.VISIBLE);

            remoteViewBottomLeft.attachDisplayId(videoViewList.get(0));
            videoMapViewList.put(videoViewList.get(0), remoteViewBottomLeft);
            remoteViewBottomRight.attachDisplayId(videoViewList.get(1));
            videoMapViewList.put(videoViewList.get(1), remoteViewBottomRight);
            remoteViewTopLeft.attachDisplayId(videoViewList.get(2));
            videoMapViewList.put(videoViewList.get(2), remoteViewTopLeft);
        }
        setLocalViewLp();
    }


    @Override
    protected void onStart() {
        super.onStart();
        localView.OpenCamera(true);
        localView.startPreview(true);
    }

    @Override
    protected void onStop() {
        super.onStop();
        localView.OpenCamera(false);
        localView.startPreview(false);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        VideoPlugin.unSetVideoCard();
    }


    private void showExitRoomDialog() {
        Log.i("qtt_debug", "showExitRoomDialog");
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("确定要退出房间吗？")
                .setCancelable(false)
                .setPositiveButton("确定",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int id) {
                                channelEngine.leave();
                            }
                        })
                .setNegativeButton("取消",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.dismiss();
                            }
                        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public int onStart(final long displayId, int width, int height) {
        Log.i("","k_test onStart  displayId:"+displayId+"  width:"+width+"  height:"+height);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                addVideoView((Long) displayId);
            }
        });
        //TODO：这个返回值需要修改不？
        return 0;
//        int rr = remoteView.attachDisplayId(displayId);
//        Log.i("","k_test onStart  rr:"+rr);
//        return rr;
    }

    @Override
    public void onFirstFrame(final long displayId, final int width, final int height) {
        Log.i("","k_test onFirstFrame  displayId:"+displayId+"  width:"+width+"  height:"+height);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setRemoteViewLayoutParams(displayId, width, height);
            }
        });
    }

    private void setRemoteViewLayoutParams(long displayId, int width, int height) {

        if (videoViewList.contains(displayId)) {

            VideoGLView temp = null;
            int[] wh = null;
            temp = videoMapViewList.get(displayId);
            View pa = (View) temp.getParent();
            Log.i("","k_test videoMapViewList:-----");
            wh = Utils.getViewWH(pa.getWidth(), pa.getHeight(), width, height);

            if (temp != null && wh != null) {
                ViewGroup.LayoutParams localViewlp = temp.getLayoutParams();
                localViewlp.width = wh[0];
                localViewlp.height = wh[1];
                temp.setLayoutParams(localViewlp);
            }
        }


    }

    /**
     * 设置本地视频的宽高
     */
    private void setLocalViewLp() {
//        int localViewWidth = localView.getWidth();
//        int[] wh = Utils.getViewWH(localView.getWidth(), localView.getHeight(), localView.width(), localView.height());
        Log.i("","k_test llVideoTopRight:-----");
        LinearLayout.LayoutParams localViewlp = (LinearLayout.LayoutParams) localView.getLayoutParams();
        int[] wh = Utils.getViewWH(llVideoTopRight.getWidth()-localViewlp.leftMargin-localViewlp.rightMargin, llVideoTopRight.getHeight()-localViewlp.topMargin-localViewlp.bottomMargin, localView.width(), localView.height());
        localViewlp.width = wh[0];
        localViewlp.height = wh[1];
        localView.setLayoutParams(localViewlp);
    }

    @Override
    public void onStop(final long displayId) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                removeVideoView((Long) displayId);
            }
        });
    }


    /**
     * 语音通道的方法实现，监听
     */
    private class ChannelObserverImpl implements ChannelObserver {
        /**
         * 进入房间成功
         */
        @Override
        public void onJoinSuccess(long roomId, long uid, ChannelRole role) {
            Log.d("qtt_debug", "onJoinSuccess roomId:" + roomId + "  role:" + role + "  ");

        }

        /**
         * 进入房间失败
         *
         * @param code
         * @param message
         */
        @Override
        public void onJoinFail(final int code, final String message) {
            Log.d("qtt_debug", "onJoinFail " + message);
            finish();
        }

        /**
         * 正在重连...
         */
        @Override
        public boolean onWaitReconnecting(int seconds) {
            Log.d("qtt_debug", "onWaitReconnecting " + seconds);
            return true;
        }

        /**
         * 网络连接断开
         */
        @Override
        public void onClose() {
            Log.d("qtt_debug", "onClose");
//            Toast.makeText(RoomActivity.this, "服务器连接断开,请重试", Toast.LENGTH_LONG).show();
            finish();
        }

        /**
         * 自己的说话状态
         *
         * @param talking
         */
        @Override
        public void onSelfTalking(int talking) {
            Log.d("qtt_debug", "onSelfTalking " + talking);
        }

        /**
         * 他人加入
         *
         * @param user
         */
        @Override
        public void onOtherJoin(ChannelUser user) {
            Log.d("qtt_debug", "onOtherJoin " + user.getUid() + ", video=" + user.isEnableVideo());
        }

        /**
         * 他人离开
         *
         * @param user
         */
        @Override
        public void onOtherLeave(ChannelUser user) {
            Log.d("qtt_debug", "onOtherLeave " + user.getUid());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, "对方退出通话", Toast.LENGTH_SHORT).show();
                    channelEngine.leave();
                }
            });
        }

        /**
         * 他人的说话状态
         *
         * @param user
         * @param talking
         */
        @Override
        public void onOtherTalking(ChannelUser user, int talking) {
            Log.d("qtt_debug", "onOtherTalking " + user.getUid() + ", talking=" + talking);
        }

        /**
         * 他人静音
         *
         * @param user
         */
        @Override
        public void onOtherMuted(ChannelUser user) {
            Log.d("qtt_debug", "onOtherMute " + user.getUid() + " " + user.isMuted());

        }

        /**
         * 他人状态改变（上麦，下麦）
         *
         * @param user
         */
        @Override
        public void onOtherRoleChanged(ChannelUser user) {
            Log.d("qtt_debug", "onOtherRoleChanged " + user.getUid() + ", 角色状态=" + user.getAudioRole());
        }

        @Override
        public void onSelfRoleChanged(ChannelRole channelRole) {
            Log.d("qtt_debug", "onSelfRoleChanged " + channelRole);
        }

        @Override
        public void onOtherNetworkStats(ChannelUser channelUser) {
        }

        @Override
        public void onSelfNetworkStats(int myRtt) {
            Log.d("qtt_debug", "onSelfNetworkStats myRtt:" + myRtt);

        }
    }
}
